//
// Created by guoshunw on 24-3-31.
//
#include "audio_src_callbacks.h"
#include "app_context.h"
#include "enum_to_string_helper.h"

namespace openmax::callbacks {
    OMX_CALLBACKTYPE audio_src_callbacks = {
            .EventHandler =
                    [](
                            OMX_OUT OMX_HANDLETYPE hComponent,
                            OMX_OUT OMX_PTR pAppData,
                            OMX_OUT OMX_EVENTTYPE eEvent,
                            OMX_OUT OMX_U32 nData1,
                            OMX_OUT OMX_U32 nData2,
                            OMX_OUT OMX_PTR pEventData) {
                        auto appCtx = static_cast<openmax::test::AppContext *>(pAppData);
                        LOG_RETURN_VAL_IF_NULL(appCtx, OMX_ErrorBadParameter)

                        if (OMX_EventError == eEvent) {
                            LOGE << "OMX_EventError, error code: " << GetEnumName(static_cast<OMX_ERRORTYPE>(nData1)) << " nData2: " << nData2;
                            return static_cast<OMX_ERRORTYPE>(nData1);
                        }
                        LOGI << "EventHandler for audio src, event " << GetEnumName(eEvent) << " nData1: " << nData1 << " nData2: " << nData2;
                        if (eEvent == OMX_EventCmdComplete) {
                            auto event_cmd = static_cast<OMX_COMMANDTYPE>(nData1);
                            if (OMX_CommandStateSet == event_cmd) {
                                auto state = static_cast<OMX_STATETYPE>(nData2);
                                switch (nData2) {
                                    case OMX_StateInvalid:
                                    case OMX_StateLoaded:
                                    case OMX_StateIdle:
                                    case OMX_StateExecuting:
                                    case OMX_StatePause:
                                    case OMX_StateWaitForResources: {
                                        LOGI << "Command state set: " << GetEnumName(state);
                                        break;
                                    }
                                    default: {
                                        LOGW << "Unknown command state set: " << GetEnumName(static_cast<OMX_STATETYPE>(nData2));
                                    } break;
                                }
                                appCtx->SemUp_src_event_sem_();
                            } else if (OMX_CommandPortEnable == event_cmd || OMX_CommandPortDisable == event_cmd) {
                                LOGI << "Command port enable or disable: "
                                     << ", nData2: " << nData2;
                                appCtx->SemUp_src_event_sem_();
                            }

                        } else if (OMX_EventPortSettingsChanged == eEvent) {
                            LOGI << "Port settings changed, nData1: " << nData1 << " nData2: " << nData2;
                        } else if (OMX_EventBufferFlag == eEvent) {
                            if (OMX_BUFFERFLAG_EOS == nData2) {
                                //                                tsem_up(appCtx.)
                            }
                        } else {
                            LOGI << "Unknown event type: " << GetEnumName(eEvent) << " nData1: " << nData1 << " nData2: " << nData2;
                        }
                        return OMX_ErrorNone;
                    },
            .EmptyBufferDone =
                    [](
                            OMX_OUT OMX_HANDLETYPE hComponent,
                            OMX_OUT OMX_PTR pAppData,
                            OMX_OUT OMX_BUFFERHEADERTYPE *pBuffer) {
                        auto appCtx = static_cast<openmax::test::AppContext *>(pAppData);
                        LOG_RETURN_VAL_IF_NULL(appCtx, OMX_ErrorBadParameter)

                        LOGI << "EmptyBufferDone for audio sink, pBuffer: " << pBuffer << ", pAppData: " << pAppData;
                        return OMX_ErrorNone;
                    },
            .FillBufferDone = [](OMX_OUT OMX_HANDLETYPE hComponent,
                                 OMX_OUT OMX_PTR pAppData,
                                 OMX_OUT OMX_BUFFERHEADERTYPE *pBuffer) {
                auto appCtx = static_cast<openmax::test::AppContext *>(pAppData);
                LOG_RETURN_VAL_IF_NULL(appCtx, OMX_ErrorBadParameter)

                LOGI << "FillBufferDone for audio sink, pBuffer: " << pBuffer << ", pAppData: " << pAppData;
                return OMX_ErrorNone; }};


}// namespace openmax::callbacks
#include "audio_src_callbacks.h"
